﻿// MedicalRulesEngine.API/Controllers/RulesController.cs
using Microsoft.AspNetCore.Mvc;
using MedicalRulesEngine.Core.Services;
using MedicalRulesEngine.Core.DTOs;
using System.ComponentModel.DataAnnotations;

namespace MedicalRulesEngine.API.Controllers;

/// <summary>
/// 规则管理控制器
/// 提供规则的CRUD操作和执行功能
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Tags("规则管理")]
public class RulesController : BaseController
{
    private readonly IRuleService _ruleService;
    private readonly ILogger<RulesController> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="ruleService">规则服务</param>
    /// <param name="logger">日志记录器</param>
    public RulesController(IRuleService ruleService, ILogger<RulesController> logger)
    {
        _ruleService = ruleService ?? throw new ArgumentNullException(nameof(ruleService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// 获取所有规则
    /// </summary>
    /// <returns>规则列表</returns>
    [HttpGet]
    [ProducesResponseType(typeof(ApiResponse<IEnumerable<RuleDto>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> GetAllRules()
    {
        try
        {
            var rules = await _ruleService.GetAllRulesAsync();
            return Success(rules, "获取规则列表成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取所有规则时发生错误");
            return Error("获取规则列表失败", 500);
        }
    }

    /// <summary>
    /// 分页获取规则
    /// </summary>
    /// <param name="pageIndex">页索引，从0开始</param>
    /// <param name="pageSize">页大小，默认10</param>
    /// <param name="searchTerm">搜索关键词</param>
    /// <param name="category">分类过滤</param>
    /// <param name="isEnabled">启用状态过滤</param>
    /// <returns>分页规则列表</returns>
    [HttpGet("paged")]
    [ProducesResponseType(typeof(PagedApiResponse<RuleDto>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> GetRulesPaged(
        [FromQuery] int pageIndex = 0,
        [FromQuery] int pageSize = 10,
        [FromQuery] string? searchTerm = null,
        [FromQuery] string? category = null,
        [FromQuery] bool? isEnabled = null)
    {
        try
        {
            if (pageIndex < 0)
                return Error("页索引不能小于0");

            if (pageSize <= 0 || pageSize > 100)
                return Error("页大小必须在1-100之间");

            var pagedResult = await _ruleService.GetRulesPagedAsync(pageIndex, pageSize, searchTerm, category, isEnabled);
            return Success(pagedResult, "获取规则列表成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "分页获取规则时发生错误");
            return Error("获取规则列表失败", 500);
        }
    }

    /// <summary>
    /// 根据ID获取规则
    /// </summary>
    /// <param name="id">规则ID</param>
    /// <returns>规则详情</returns>
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(ApiResponse<RuleDto>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> GetRuleById([FromRoute] string id)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(id))
                return Error("规则ID不能为空");

            var rule = await _ruleService.GetRuleByIdAsync(id);
            if (rule == null)
                return NotFound($"未找到ID为 {id} 的规则");

            return Success(rule, "获取规则详情成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "根据ID获取规则时发生错误，ID: {RuleId}", id);
            return Error("获取规则详情失败", 500);
        }
    }

    /// <summary>
    /// 根据代码获取规则
    /// </summary>
    /// <param name="code">规则代码</param>
    /// <returns>规则详情</returns>
    [HttpGet("by-code/{code}")]
    [ProducesResponseType(typeof(ApiResponse<RuleDto>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> GetRuleByCode([FromRoute] string code)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(code))
                return Error("规则代码不能为空");

            var rule = await _ruleService.GetRuleByCodeAsync(code);
            if (rule == null)
                return NotFound($"未找到代码为 {code} 的规则");

            return Success(rule, "获取规则详情成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "根据代码获取规则时发生错误，Code: {RuleCode}", code);
            return Error("获取规则详情失败", 500);
        }
    }

    /// <summary>
    /// 根据工作流获取规则
    /// </summary>
    /// <param name="workflowName">工作流名称</param>
    /// <returns>规则列表</returns>
    [HttpGet("by-workflow/{workflowName}")]
    [ProducesResponseType(typeof(ApiResponse<IEnumerable<RuleDto>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> GetRulesByWorkflow([FromRoute] string workflowName)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(workflowName))
                return Error("工作流名称不能为空");

            var rules = await _ruleService.GetRulesByWorkflowAsync(workflowName);
            return Success(rules, $"获取工作流 {workflowName} 的规则列表成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "根据工作流获取规则时发生错误，Workflow: {WorkflowName}", workflowName);
            return Error("获取规则列表失败", 500);
        }
    }

    /// <summary>
    /// 根据分类获取规则
    /// </summary>
    /// <param name="category">分类</param>
    /// <returns>规则列表</returns>
    [HttpGet("by-category/{category}")]
    [ProducesResponseType(typeof(ApiResponse<IEnumerable<RuleDto>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> GetRulesByCategory([FromRoute] string category)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(category))
                return Error("分类不能为空");

            var rules = await _ruleService.GetRulesByCategoryAsync(category);
            return Success(rules, $"获取分类 {category} 的规则列表成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "根据分类获取规则时发生错误，Category: {Category}", category);
            return Error("获取规则列表失败", 500);
        }
    }

    /// <summary>
    /// 搜索规则
    /// </summary>
    /// <param name="searchTerm">搜索关键词</param>
    /// <param name="category">分类过滤</param>
    /// <param name="isEnabled">启用状态过滤</param>
    /// <returns>符合条件的规则列表</returns>
    [HttpGet("search")]
    [ProducesResponseType(typeof(ApiResponse<IEnumerable<RuleDto>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> SearchRules(
        [FromQuery] string? searchTerm = null,
        [FromQuery] string? category = null,
        [FromQuery] bool? isEnabled = null)
    {
        try
        {
            var rules = await _ruleService.SearchRulesAsync(searchTerm, category, isEnabled);
            return Success(rules, "搜索规则成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "搜索规则时发生错误");
            return Error("搜索规则失败", 500);
        }
    }

    /// <summary>
    /// 创建规则
    /// </summary>
    /// <param name="request">创建规则请求</param>
    /// <returns>创建的规则</returns>
    [HttpPost]
    [ProducesResponseType(typeof(ApiResponse<RuleDto>), 201)]
    [ProducesResponseType(typeof(ValidationApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> CreateRule([FromBody] CreateRuleRequest request)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                var errors = ModelState.Values
                    .SelectMany(v => v.Errors)
                    .Select(e => e.ErrorMessage);
                return ValidationError(errors);
            }

            var rule = await _ruleService.CreateRuleAsync(request);
            return CreatedAtAction(nameof(GetRuleById), new { id = rule.Id },
                new ApiResponse<RuleDto>
                {
                    Success = true,
                    Message = "创建规则成功",
                    Data = rule,
                    Timestamp = DateTime.UtcNow
                });
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning(ex, "创建规则时发生业务错误");
            return Error(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建规则时发生错误");
            return Error("创建规则失败", 500);
        }
    }

    /// <summary>
    /// 更新规则
    /// </summary>
    /// <param name="id">规则ID</param>
    /// <param name="request">更新规则请求</param>
    /// <returns>更新后的规则</returns>
    [HttpPut("{id}")]
    [ProducesResponseType(typeof(ApiResponse<RuleDto>), 200)]
    [ProducesResponseType(typeof(ValidationApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> UpdateRule([FromRoute] string id, [FromBody] UpdateRuleRequest request)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(id))
                return Error("规则ID不能为空");

            if (!ModelState.IsValid)
            {
                var errors = ModelState.Values
                    .SelectMany(v => v.Errors)
                    .Select(e => e.ErrorMessage);
                return ValidationError(errors);
            }

            var rule = await _ruleService.UpdateRuleAsync(id, request);
            return Success(rule, "更新规则成功");
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning(ex, "更新规则时发生参数错误，ID: {RuleId}", id);
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新规则时发生错误，ID: {RuleId}", id);
            return Error("更新规则失败", 500);
        }
    }

    /// <summary>
    /// 删除规则
    /// </summary>
    /// <param name="id">规则ID</param>
    /// <returns>删除结果</returns>
    [HttpDelete("{id}")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> DeleteRule([FromRoute] string id)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(id))
                return Error("规则ID不能为空");

            await _ruleService.DeleteRuleAsync(id);
            return Success("删除规则成功");
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning(ex, "删除规则时发生参数错误，ID: {RuleId}", id);
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除规则时发生错误，ID: {RuleId}", id);
            return Error("删除规则失败", 500);
        }
    }

    /// <summary>
    /// 启用规则
    /// </summary>
    /// <param name="id">规则ID</param>
    /// <returns>操作结果</returns>
    [HttpPost("{id}/enable")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> EnableRule([FromRoute] string id)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(id))
                return Error("规则ID不能为空");

            await _ruleService.EnableRuleAsync(id);
            return Success("启用规则成功");
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning(ex, "启用规则时发生参数错误，ID: {RuleId}", id);
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "启用规则时发生错误，ID: {RuleId}", id);
            return Error("启用规则失败", 500);
        }
    }

    /// <summary>
    /// 禁用规则
    /// </summary>
    /// <param name="id">规则ID</param>
    /// <returns>操作结果</returns>
    [HttpPost("{id}/disable")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> DisableRule([FromRoute] string id)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(id))
                return Error("规则ID不能为空");

            await _ruleService.DisableRuleAsync(id);
            return Success("禁用规则成功");
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning(ex, "禁用规则时发生参数错误，ID: {RuleId}", id);
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "禁用规则时发生错误，ID: {RuleId}", id);
            return Error("禁用规则失败", 500);
        }
    }

    /// <summary>
    /// 复制规则
    /// </summary>
    /// <param name="id">源规则ID</param>
    /// <param name="request">复制规则请求</param>
    /// <returns>复制后的规则</returns>
    [HttpPost("{id}/clone")]
    [ProducesResponseType(typeof(ApiResponse<RuleDto>), 201)]
    [ProducesResponseType(typeof(ValidationApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> CloneRule([FromRoute] string id, [FromBody] CloneRuleRequest request)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(id))
                return Error("规则ID不能为空");

            if (!ModelState.IsValid)
            {
                var errors = ModelState.Values
                    .SelectMany(v => v.Errors)
                    .Select(e => e.ErrorMessage);
                return ValidationError(errors);
            }

            var rule = await _ruleService.CloneRuleAsync(id, request.NewName, request.NewCode);
            return CreatedAtAction(nameof(GetRuleById), new { id = rule.Id },
                new ApiResponse<RuleDto>
                {
                    Success = true,
                    Message = "复制规则成功",
                    Data = rule,
                    Timestamp = DateTime.UtcNow
                });
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning(ex, "复制规则时发生参数错误，ID: {RuleId}", id);
            return NotFound(ex.Message);
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning(ex, "复制规则时发生业务错误，ID: {RuleId}", id);
            return Error(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "复制规则时发生错误，ID: {RuleId}", id);
            return Error("复制规则失败", 500);
        }
    }

    /// <summary>
    /// 验证规则
    /// </summary>
    /// <param name="rule">规则对象</param>
    /// <returns>验证结果</returns>
    [HttpPost("validate")]
    [ProducesResponseType(typeof(ApiResponse<System.ComponentModel.DataAnnotations.ValidationResult>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> ValidateRule([FromBody] RuleDto rule)
    {
        try
        {
            var validationResult = await _ruleService.ValidateRuleAsync(rule);
            return Success(validationResult, "规则验证完成");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证规则时发生错误");
            return Error("验证规则失败", 500);
        }
    }

    /// <summary>
    /// 执行规则
    /// </summary>
    /// <param name="id">规则ID</param>
    /// <param name="inputData">输入数据</param>
    /// <returns>执行结果</returns>
    [HttpPost("{id}/execute")]
    [ProducesResponseType(typeof(ApiResponse<RuleExecutionResult>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> ExecuteRule([FromRoute] string id, [FromBody] object inputData)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(id))
                return Error("规则ID不能为空");

            var result = await _ruleService.ExecuteRuleAsync(id, inputData);
            return Success(result, "规则执行完成");
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning(ex, "执行规则时发生参数错误，ID: {RuleId}", id);
            return NotFound(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "执行规则时发生错误，ID: {RuleId}", id);
            return Error("执行规则失败", 500);
        }
    }

    /// <summary>
    /// 执行工作流规则
    /// </summary>
    /// <param name="workflowName">工作流名称</param>
    /// <param name="inputData">输入数据</param>
    /// <returns>执行结果列表</returns>
    [HttpPost("execute-workflow/{workflowName}")]
    [ProducesResponseType(typeof(ApiResponse<IEnumerable<RuleExecutionResult>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 500)]
    public async Task<IActionResult> ExecuteWorkflowRules([FromRoute] string workflowName, [FromBody] object inputData)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(workflowName))
                return Error("工作流名称不能为空");

            var results = await _ruleService.ExecuteWorkflowRulesAsync(workflowName, inputData);
            return Success(results, $"工作流 {workflowName} 执行完成");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "执行工作流规则时发生错误，Workflow: {WorkflowName}", workflowName);
            return Error("执行工作流规则失败", 500);
        }
    }
}

/// <summary>
/// 复制规则请求
/// </summary>
public class CloneRuleRequest
{
    /// <summary>
    /// 新规则名称
    /// </summary>
    [Required(ErrorMessage = "新规则名称不能为空")]
    [StringLength(100, ErrorMessage = "新规则名称长度不能超过100个字符")]
    public string NewName { get; set; } = string.Empty;

    /// <summary>
    /// 新规则代码
    /// </summary>
    [Required(ErrorMessage = "新规则代码不能为空")]
    [StringLength(50, ErrorMessage = "新规则代码长度不能超过50个字符")]
    [RegularExpression(@"^[a-zA-Z][a-zA-Z0-9_]*$", ErrorMessage = "规则代码必须以字母开头，只能包含字母、数字和下划线")]
    public string NewCode { get; set; } = string.Empty;
}
